package com.bilibili.chatonline.util.db;



import com.bilibili.chatonline.common.CommonText;
import com.bilibili.chatonline.util.ReadProperties;

import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 连接池缩容管理器，负责定时检查并关闭闲置连接
 */
public class ConnectionPoolShrinker {
    private final DBPool dbPool;
    private final long checkInterval; // 检查间隔（毫秒）
    private final long maxIdleTime;   // 最大闲置时间（毫秒）
    // 定时任务执行器
    private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

    public ConnectionPoolShrinker(DBPool dbPool) throws IOException {
        checkInterval=Integer.parseInt(ReadProperties.getProperty(CommonText.DataSource+"pool.check-interval"));
        maxIdleTime=Integer.parseInt(ReadProperties.getProperty(CommonText.DataSource+"pool.max-idle-time"));
        this.dbPool = dbPool;
    }

    /**
     * 启动定时缩容任务
     */
    public void start() {
        scheduler.scheduleAtFixedRate(this::shrinkConnections,
                checkInterval,
                checkInterval,
                TimeUnit.MILLISECONDS);
        System.out.println("连接池缩容任务已启动，检查间隔: " + checkInterval + "ms");
    }

    /**
     * 执行缩容逻辑
     */
    private void shrinkConnections() {
        synchronized (dbPool) {
            long currentTime = System.currentTimeMillis();
            int shrinkCount = 0;

            // 如果当前连接数小于等于初始连接数，不进行缩容
            if (dbPool.getPoolSize() <= dbPool.getInitSize()) {
                return;
            }

            // 计算最多可关闭的连接数量
            int maxCloseCount = dbPool.getCounter() - dbPool.getInitSize();

            // 检查并关闭闲置超时的连接
            while (shrinkCount < maxCloseCount && !dbPool.getPool().isEmpty()) {
                ConcreteConnection concreteConnection = dbPool.getPool().peek();

                if (currentTime - concreteConnection.getLastUsedTime() > maxIdleTime) {
                    concreteConnection = dbPool.getPool().poll();
                    dbPool.closeConnection(concreteConnection.getConnection());
                    dbPool.setCounter(dbPool.getCounter() - 1);
                    shrinkCount++;
                } else {
                    // 队列是FIFO的，后面的连接闲置时间更短，无需继续检查
                    break;
                }
            }

            if (shrinkCount > 0) {
                System.out.println("连接池缩容完成，关闭了 " + shrinkCount +
                        " 个闲置连接，当前总连接数: " + dbPool.getCounter());
            }
        }
    }

    /**
     * 停止定时任务
     */
    public void stop() {
        scheduler.shutdown();
        System.out.println("连接池缩容任务已停止");
    }
}
